/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
var mxCodecRegistry = {
  /**
   * Class: mxCodecRegistry
   *
   * Singleton class that acts as a global registry for codecs.
   *
   * Adding an <mxCodec>:
   *
   * 1. Define a default codec with a new instance of the
   * object to be handled.
   *
   * (code)
   * var codec = new mxObjectCodec(new mxGraphModel());
   * (end)
   *
   * 2. Define the functions required for encoding and decoding
   * objects.
   *
   * (code)
   * codec.encode = function(enc, obj) { ... }
   * codec.decode = function(dec, node, into) { ... }
   * (end)
   *
   * 3. Register the codec in the <mxCodecRegistry>.
   *
   * (code)
   * mxCodecRegistry.register(codec);
   * (end)
   *
   * <mxObjectCodec.decode> may be used to either create a new
   * instance of an object or to configure an existing instance,
   * in which case the into argument points to the existing
   * object. In this case, we say the codec "configures" the
   * object.
   *
   * Variable: codecs
   *
   * Maps from constructor names to codecs.
   */
  codecs: [],

  /**
   * Variable: aliases
   *
   * Maps from classnames to codecnames.
   */
  aliases: [],

  /**
   * Function: register
   *
   * Registers a new codec and associates the name of the template
   * constructor in the codec with the codec object.
   *
   * Parameters:
   *
   * codec - <mxObjectCodec> to be registered.
   */
  register: function (codec) {
    if (codec != null) {
      var name = codec.getName();
      mxCodecRegistry.codecs[name] = codec;

      var classname = mxUtils.getFunctionName(codec.template.constructor);

      if (classname != name) {
        mxCodecRegistry.addAlias(classname, name);
      }
    }

    return codec;
  },

  /**
   * Function: addAlias
   *
   * Adds an alias for mapping a classname to a codecname.
   */
  addAlias: function (classname, codecname) {
    mxCodecRegistry.aliases[classname] = codecname;
  },

  /**
   * Function: getCodec
   *
   * Returns a codec that handles objects that are constructed
   * using the given constructor.
   *
   * Parameters:
   *
   * ctor - JavaScript constructor function.
   */
  getCodec: function (ctor) {
    var codec = null;

    if (ctor != null) {
      var name = mxUtils.getFunctionName(ctor);
      var tmp = mxCodecRegistry.aliases[name];

      if (tmp != null) {
        name = tmp;
      }

      codec = mxCodecRegistry.codecs[name];

      // Registers a new default codec for the given constructor
      // if no codec has been previously defined.
      if (codec == null) {
        try {
          codec = new mxObjectCodec(new ctor());
          mxCodecRegistry.register(codec);
        } catch (e) {
          // ignore
        }
      }
    }

    return codec;
  },
};
